20180510 AMG專輯篩選練習
前面的部分和前節的代碼相同,
這次要做的只是完善換頁時的重複賦值部份而已。
首先一樣,先導入模組、建立label字典,以及給定post需要用到的headers和data。
from seleniumrequests import Chrome
import requests
import re
from bs4 import BeautifulSoup
chrome_path = r"C:\Users\Ramone\seleniumdriver\chrome\chromedriver.exe" # 給定一個瀏覽器的local位置
webdriver = Chrome(chrome_path) # 導入Chorme當作webdriver
#建立Label字典
label_res= webdriver.request('GET','https://www.allmusic.com/advanced-search/')
label_soup = BeautifulSoup(label_res.text,"lxml")
label = label_soup.find_all('input',{'id':re.compile('genreid.*?')})
label_dict={}
for l in label:
label_dict[l['value']]=l['id']
#建立評價字典
rating_dict={}
star=1.0
for i in range(1,10):
rating_dict[str(star)]='editorialrating:'+str(i)
star+=0.5
#headers直接從network複製
amg_header={
'accept': r'text/html, */*; q=0.01',
'accept-encoding': r'gzip, deflate, br',
'accept-language': r'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6',
'content-length': '39',
'content-type': r'application/x-www-form-urlencoded; charset=UTF-8',
'cookie': r'_ga=GA1.2.85029673.1513518205; __gads=ID=3275e8321c618a22:T=1513518176:S=ALNI_MbT7eOHrtfYxgOBlXi-4NZzwkA01Q; __qca=P0-704611526-1513518207321; policy=notified; registration_prompt=true; _gid=GA1.2.939754473.1525263314; bm_monthly_unique=true; allmusic_session=a%3A6%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22498c8bf394d58ea40993a276a34e6bfc%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A11%3A%2210.128.8.22%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A115%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F65.0.3325.181+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1525278399%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22user%22%3Bi%3A0%3B%7Dedeeacbf1b0d945d29d143bc59a40129; _gat=1; _gat_cToolbarTracker=1; bm_last_load_status=BLOCKING; bm_daily_unique=true; bm_sample_frequency=100',
'origin': r'https://www.allmusic.com',
'referer': r'https://www.allmusic.com/advanced-search',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
'x-requested-with': 'XMLHttpRequest',
}
#formdata
label_input= input("請輸入音樂類別 (Geners & Styles) ex:Country-Folk : ")
while label_input not in label_dict:
label_input= input("類別不存在,請確認後重新輸入,或輸入""label_dict""查詢所有類別: ")
if label_input == 'label_dict':
for k in label_dict:
print (k)
rating_input = input("請輸入評價幾顆星 (All Music Raing) ex:5.0 :")
while rating_input not in rating_dict:
rating_input= input("請輸入評價幾顆星 1.0/ 1.5/ 2.0/ 2.5/ 3.0/ 3.5/ 4.0/ 4.5/ 5.0: ")
#替input的資訊給一個value_name
amg_label=label_dict[label_input]
amg_rating=rating_dict[rating_input]
再來處理換頁的部分,
用開發人員工具(network)去檢查換頁的規則,發現其實很容易,
只會有url的尾碼數字不同,headers和data都沒有變化,
我們用bs和正則表達把變化的url挑出來。
接著將完整的url網址(amg_url+next_url),餵給next_res這個value。
#將headers,data包給selenium-request做post請求
webdriver = Chrome(chrome_path)
res= webdriver.request('POST','https://www.allmusic.com/advanced-search/results/'
,headers=amg_header,data="filters[]=%s&filters[]=%s" %(amg_label,amg_rating))
res_soup = BeautifulSoup(res.text,'lxml')
#用開發人員工具,找到換頁的模式的規則產生下一次的respond
next_page = res_soup.find_all('span',{'class':'next'})
amg_url = 'https://www.allmusic.com/'
next_url=re.compile(r'(?=/advanced-search/results/)/advanced-search/results/\d+')
next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
因為程度不好,後面在輸出資料的代碼邏輯寫得很冗長,
這邊我先定義一些functino以便之後重複使用,
(這部分因為觀念不好,花了很多時間。)
#建立一個BS抓取原始碼的function並用class包裝起來,便於之後取用。 (用字典的形式也可以)
class get_info():
def __init__(self,artist,title,year):
self.artist=artist
self.title=title
self.year=year
def get_source():
artist = res_soup.find_all('td',{'class':'artist'})
title = res_soup.find_all('td',{'class':'title'})
year = res_soup.find_all('td',{'class':'year'})
return get_info(artist,title,year)
# return {'artist':artist,'title':title,'year':year} (用字典的形式也可以)
#建立濾除換行符號並加入list的function,這部分是方便到之後做迴圈輸出需要。
def add_list(y):
y_list=[]
for x in y:
x_text=x.text
x_str=x_text.strip()
y_list.append(x_str)
return y_list
最後就是輸出我們需要的資料了,
next_page為bs剖析完的list,(bs剖析有找到下一頁的時候,不為空的list)
我們以next_page當作判別式,
將輸出的部分,只有一頁時,或是多頁時來編碼,如下:
#只有一頁的時候就做這個,把當頁的資料做bs剖析並做迴圈打印list。
print ('>>>page<<<' )
i=0
while i <len(add_list(get_source().title)):
print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
i=i+1
#有很多頁的話就做這個
while next_page != []:
#把下一頁的url丟到post重新做打印
res= webdriver.request('POST',next_res,headers=amg_header,data="filters[]=%s&filters[]=%s" %(amg_label,amg_rating))
res_soup = BeautifulSoup(res.text,'lxml')
print ('>>>page<<<' )
i=0
while i <len(add_list(get_source().title)):
print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
i=i+1
#當下一頁的post結果又有找到下一頁時,將next_res重新賦值,持續到 next_page為空
next_page = res_soup.find_all('span',{'class':'next'})
if next_page != []:
next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
#只有一頁的時候就做這個
if next_page == []:
print ('>>>page<<<' )
i=0
while i <len(add_list(get_source().title)):
print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
i=i+1
#有很多頁的時候就做這個
else:
#先把下一頁的網址包起來
next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
#還有下一頁之後就持續打印
while next_page != []:
print ('>>>page<<<' )
i=0
while i <len(add_list(get_source().title)):
print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
i=i+1
#並把下一頁的原始碼餵到下一次爬蟲
res= webdriver.request('POST',next_res,headers=amg_header,data="filters[]=%s&filters[]=%s" %(amg_label,amg_rating))
res_soup = BeautifulSoup(res.text,'lxml')
next_page = res_soup.find_all('span',{'class':'next'})
#如果還有下一頁就再更新一次下一頁的網址,如果沒有就把最後一頁印出來
if next_page != []:
next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
else:
print ('>>>page<<<' )
i=0
while i <len(add_list(get_source().title)):
print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
i=i+1
大功告成,
此次練習是從"音樂類別"和"評價"去做Post,
但實際上聽音樂時我們怎麼會知道這種類型的音樂分類是什麼呢,
所以這樣開頭的體驗其實不是很人性化,
如果我們可以從某樂團、或專輯開始,也許是一個更好的主意。
(也許可以從google做判別導向,再把資料轉換過後丟給AMG或其他有公信力的網站做爬蟲)
Source credit: All Music : https://www.allmusic.com/
No copyright infringement intended.